package eu.winterwheels.enterprise.data;

import java.util.logging.Logger;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import net.webservicex.CdataToXmlReader;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import eu.winterwheels.enterprise.model.Country;

@RequestScoped
public class CountryData {
	private final int ISO_CODE_SIZE = 2;
	@Inject
	private Logger log;
	@Inject
	private EntityManager em;
	private Country country;

	public Country getCountryByCode(String iso2digitCountryCode) {
		country = ensureCountryPersistence(iso2digitCountryCode);
		return country;
	}

	private Country ensureCountryPersistence(String iso2digitCountryCode) {
		country = em.find(Country.class, iso2digitCountryCode);
		// Was this country persisted before?
		if (country == null) {
			// If not, retrieve the country data from external source.
			country = new Country();
			if (isCountry(iso2digitCountryCode)) {
				country.setCountryCode(iso2digitCountryCode);
				populateCountryData();
				em.persist(country);
			} else {
				log.fine("Request for country that doesn't exist");
			}			
		}
		return country;
	}

	private void populateCountryData() {
		//TODO used to employ the WSDL from webservicex.net
		// get countryname
//		String countryCData = getCountrySoap().getCountryByCountryCode(
//				country.getCountryCode());
//		country.setCountryName(retrieveNodeValue(countryCData, "//Table/name")
//				.getNodeValue());
//
//		String countryCurrency = getCountrySoap().getCurrencyByCountry(country.getCountryName());
//		country.setCurrency(retrieveNodeValue(countryCurrency, "//Table/CurrencyCode")
//				.getNodeValue());
//		
//		String countryGMT = getCountrySoap().getGMTbyCountry(country.getCountryName());
//		country.setGmtZone(retrieveNodeValue(countryGMT, "//Table/GMT")
//				.getNodeValue());
//		
//		String countryIsd = getCountrySoap().getISD(country.getCountryName());
//		country.setIsd(Short.parseShort(retrieveNodeValue(countryIsd, "//Table/code")
//				.getNodeValue()));
	}

	private Node retrieveNodeValue(String cData, String xPathString) {
		Document doc = null;
		try {
			cData = cData.replaceAll("\n", "");
			doc = CdataToXmlReader.loadXMLFromString(cData);

		} catch (Exception e) {
			e.printStackTrace();
		}
		XPath xPath = XPathFactory.newInstance().newXPath();
		Node node = null;
		try {
			node = (Node) xPath.evaluate(xPathString, doc.getDocumentElement(),
					XPathConstants.NODE);
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		if (node != null && node.getFirstChild() != null
				&& node.getFirstChild().getNodeValue() != null)
			return node.getFirstChild();

		return null;
	}

	private boolean isCountry(String iso2digitCountryCode) {
		if (iso2digitCountryCode.length() == ISO_CODE_SIZE) {
			String countryCData = "";//getCountrySoap().getCountryByCountryCode(
//					iso2digitCountryCode);
			if (countryCData == null || countryCData.isEmpty()) {
				return false;
			} else {
				Node node = retrieveNodeValue(countryCData,
						"//NewDataSet/Table");
				if (node != null)
					return true;
			}
		}
		return false;
	}

//	private CountrySoap getCountrySoap() {
//		net.webservicex.country.Country service = new net.webservicex.country.Country();
//		log.fine("Create Web Service: " + service.toString());
//		return service.getCountrySoap();
//	}

}
